package stu.xjtu.physical.common.handler;

import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import stu.xjtu.physical.common.JsonResponse;
import stu.xjtu.physical.common.constant.MessageConstant;
import stu.xjtu.physical.common.exception.BaseException;

import java.sql.SQLIntegrityConstraintViolationException;
import java.util.ArrayList;
import java.util.List;

/**
 * 全局异常处理器，处理项目中抛出的业务异常
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 捕获业务异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler
    public JsonResponse exceptionHandler(BaseException ex) {
        log.error("异常信息：{}", ex.getMessage());
        return JsonResponse.failure(ex.getMessage());
    }

    /**
     * 处理sql异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler
    public JsonResponse exceptionHander(SQLIntegrityConstraintViolationException ex) {
        String message = ex.getMessage();
        // Duplicate entry 'liyi' for key 'employee.idx_username'
        if (message.contains("Duplicate entry")) {
            String[] split = message.split(" ");
            String username = split[2];
            String msg = username + MessageConstant.ALREADY_EXITS;
            return JsonResponse.failure(msg);
        } else {
            return JsonResponse.failure(MessageConstant.UNKNOWN_ERROR);
        }
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public JsonResponse validationBodyException(MethodArgumentNotValidException exception) {
        BindingResult result = exception.getBindingResult();
        ArrayList<String> resp = new ArrayList<>();
        if (result.hasErrors()) {
            List<ObjectError> errors = result.getAllErrors();
            errors.forEach(p -> {
                FieldError fieldError = (FieldError) p;
                log.error("Data check failure : object{" + fieldError.getObjectName() + "},field{" + fieldError.getField() +
                        "},errorMessage{" + fieldError.getDefaultMessage() + "}");
                resp.add(fieldError.getDefaultMessage());
            });
        }
        return JsonResponse.failure(resp.toString());
    }
}
